﻿#ifndef _NAND_GD5_H
#define _NAND_GD5_H

#include "nand_spi.h"
//////////////////////////////////////////////////////////////////////////////////
// 状态描述：
// OPT-E  :控制读写命名操作的是主存储区或者OPT存储区
// P_FAIL : 编程失败 - 编程地址无效或者区域受保护 - 执行编程或者执行RESET清零
// E_FAIL : 擦除失败 - 擦除地址无效或者区域受保护 - 执行擦除或者执行RESET清零 
// WEL    : 写使能   - 1=enable, 0=disable, 执行编程或擦除指令时会自动清除WEL
// OIP    ：忙状态   - 读页，执行编程，擦除，reset后进入忙状态
// 
// ECCS1---ECCS0---ECCSE1---ECCSE0---
// 0       0       x        x     ---No bit errors were detected during the previous read algorithm
// 0       1       0        0     ---Bit errors(<4) were detected and corrected
// 0       1       0        1     ---Bit errors(=5) were detected and corrected
// 0       1       1        0     ---Bit errors(=6) were detected and corrected
// 1       0       x        x     ---Bit errors greater than ECC capability(8 bits) and not corrected
// 1       1       x        x     ---Bit errors reach ECC capability( 8 bits) and corrected
//////////////////////////////////////////////////////////////////////////////////

/*flash info*/
#define GD5_PAGE_MAIN_SIZE               2048
#define GD5_PAGE_SPARE_SIZE              64
#define GD5_PAGE_SIZE                    (GD5_PAGE_MAIN_SIZE + GD5_PAGE_SPARE_SIZE)
#define GD5_PAGE_PER_BLOCK               64            
#define GD5_BLOCK_TOTAL                  1024


/*cmd define*/
#define GD5_CMD_WRITE_ENABLE             0x06
#define GD5_CMD_WRITE_DISABLE            0x04

#define GD5_CMD_FEATURE_GET              0x0F
#define GD5_CMD_FEATURE_SET              0x1F

#define GD5_FEATURE_1_PROTECTION         0xA0  //PROTECT
#define GD5_FEATURE_2_CFG                0xB0  //CFG  ,除 OTP_PRT 均可外可设定
#define GD5_FEATURE_3_STATUS             0xC0  //ST
#define GD5_FEATURE_4                    0xD0  //
#define GD5_FEATURE_5                    0xF0  //ECC ST

#define GD5_CMD_READ_ID                  0x9F                  

#define GD5_CMD_PAGE_READ                0x13  //read page to cache
#define GD5_CMD_CACHE_READ               0x03  //read data from cache
#define GD5_CMD_CACHE_READ_FAST          0x0B  //read data from cache
#define GD5_CMD_CACHE_READ_X4            0x6B  //read data from cache  //cmd and addr is spi, data is qspi

#define GD5_CMD_PROGRAM_LOAD             0x02  //写cache，未写的部分会被填充为0xFF
#define GD5_CMD_PROGRAM_LOAD_X4          0x32  //写cache，未写的部分会被填充为0xFF  //cmd and addr is spi, data is qspi

#define GD5_CMD_PROGRAM_EXE              0x10  //写cache，未写的部分会被填充为0xFF

#define GD5_CMD_PROGRAM_LOAD_RANDOM      0x84  //写cache，未写的部分不变
#define GD5_CMD_PROGRAM_LOAD_RANDOM_X4   0x34  //写cache，未写的部分不变

#define GD5_CMD_BLOCK_ERASE              0xD8

#define GD5_CMD_RESET                    0xFF

/*chip reset*/
void gd5_reset(void);

uint8_t gd5_featute_get(uint8_t reg_addr);
void gd5_featute_set(uint8_t reg_addr, uint8_t dat);

uint8_t gd5_wait_ready(void);

uint8_t gd5_ecc_error_get(void);

uint8_t gd5_write_enable(void);
uint8_t gd5_write_disable(void);

void gd5_read_id(uint8_t *dat);

uint8_t gd5_read_page(uint32_t page_addr);
uint8_t gd5_read_cache(uint16_t coil_addr, uint8_t * dat, uint16_t Len);
uint8_t gd5_write_cache(uint16_t coil_addr, uint8_t * dat, uint16_t Len);
uint8_t gd5_q_read_cache(uint16_t coil_addr, uint8_t * dat, uint16_t Len);
uint8_t gd5_q_write_cache(uint16_t coil_addr, uint8_t * dat, uint16_t Len);
uint8_t gd5_program_exe(uint32_t page_addr);

uint8_t gd5_block_erase(uint32_t block_addr);
uint8_t gd5_chip_erase(void);


uint8_t gd5_opt_mem_select(void);
uint8_t gd5_main_mem_select(void);

uint8_t gd5_init(void);

#endif
